# -*- coding: utf-8 -*-
import os
import pandas as pd
from src.sharedSrc import getSetting, extract_value_and_unit
from dataload.t3Merge import Merge
from deps.ui.popupLoading import Loading


class DataAnalysis:
    def __init__(self, filePath: str):
        self.measure_list = None
        self.rmNa = None
        self.df = None
        self.filePath = filePath
        self.settings = getSetting()
        self.dataLode()  # 数据表层信息
        self.metaDataList = self.check_bin()  # 数据表层信息
        self.testSelectionList = self.testSelection()
        self.testName = self.getTestName()

    def dataLode(self):
        """获取数据表层信息"""

        # 读取pkl文件加快处理速度
        if self.filePath.endswith('.pkl'):
            self.df = pd.read_pickle(self.filePath)

        elif self.filePath.endswith('.txt'):
            m = Merge()
            m.txtToCsv(self.filePath)
            m.toCSV(self.filePath)
            self.df = m.df
        else:
            if self.filePath.endswith('.csv'):
                header = pd.read_csv(self.filePath, nrows=0)
                get_header = [i for i in header if "Result" not in i]
                self.df = pd.read_csv(self.filePath, dtype=str, usecols=get_header)
            elif self.filePath.endswith('.xlsx'):
                # Step 1: Read the Excel file to get the column names
                all_columns = pd.read_excel(self.filePath, nrows=0).columns.tolist()
                # Step 2: Filter out columns that contain "Result"
                get_header = [col for col in all_columns if "Result" not in col]
                # Step 3: Re-read the Excel file using the filtered columns
                self.df = pd.read_excel(self.filePath, dtype=str, usecols=get_header)


        # 数据重写初始化 防止加载上次数据
        self.rmNa = None

    def check_bin(self):
        metaDataList = [["File Name: ", os.path.basename(self.filePath)],
                        ["Directory Path: ", os.path.dirname(self.filePath)],
                        ["File Size: ", self.get_file_size(self.filePath)], ["Wafers Tested: ", '1']]

        get_bin = self.get_bin()
        if get_bin is not None:
            metaDataList.append(["DUTs Tested: ", get_bin[0]])
            metaDataList.append(["DUTs Passed: ", get_bin[1]])
            metaDataList.append(["DUTs Failed: ", get_bin[2]])
        metaDataList.append(["CDASystem Version: ", "V1.1.0"])

        return metaDataList
    def testSelection(self) -> list:
        """获得 test select 项"""
        """def testSelection(self):
            test_select_list = []
            # 获得 test select 项
            TestName = self.df["TestName"].dropna()  # 移除缺省值
            Signal = self.df["Signal"].dropna()  # 移除缺省值
            for testName, signal in zip(TestName, Signal):
                if testName == " " and signal == " ":
                    continue
                test_select_list.append(testName + "\t" + signal)
            return test_select_list"""
        # Drop rows with missing values in either 'TestName' or 'Signal' columns
        filtered_df = self.df.dropna(subset=["TestName", "Signal"])

        # Filter out rows where 'TestName' or 'Signal' contains an empty string " "
        filtered_df = filtered_df[(filtered_df["TestName"] != "") & (filtered_df["Signal"] != "")]

        # Create the test_select_list using vectorized operations
        test_select_list = (filtered_df["TestName"] + "\t" + filtered_df["Signal"]).tolist()

        return test_select_list

    def get_bin(self) -> [str, str, str, dict]:
        """获得bin的种类 和测试项"""
        classification = {}
        pass_result = 0
        error_result = 0
        if self.measure_list is None:
            self.measure_list = [col for col in self.df.columns if 'Measure' in col]

        # for
        Bin = self.df[self.df['Force'] == 'Bin']

        for i in self.measure_list:
            xyData = Bin[i].values[0]
            if xyData in classification:
                classification[xyData] += 1
            else:
                classification[xyData] = 1
        pass_bin = self.settings.pass_bin

        for key in classification.keys():
            if key == pass_bin:
                pass_result += classification[key]
            else:
                error_result += classification[key]
        all_test = pass_result + error_result

        return str(all_test), str(pass_result), str(error_result), classification

    def get_measure_key(self, split):
        wafer_dict = {}
        for i in range(16):
            # 使用格式化字符串将整数转换为十六进制字符串（小写），并确保它是单个字符
            hex_key = format(i, 'x').zfill(1)
            wafer_dict[hex_key] = i

        for i in range(split):
            wafer_dict['split_' + str(i)] = i
        return wafer_dict

    def get_cate(self) -> dict:
        """获得bin的种类 和测试项"""
        classification = {}
        if self.measure_list is None:
            self.measure_list = [col for col in self.df.columns if 'Measure' in col]
        # for
        Bin = self.df[self.df['Force'] == 'Cate']

        for i in self.measure_list:
            xyData = Bin[i].values[0]
            if xyData in Bin:
                classification[xyData] += 1
            else:
                classification[xyData] = 1

        return classification

    def separate_head(self) -> list:
        """分离csv头部信息"""

        if not (self.filePath.endswith(".csv") or self.filePath.endswith(".xlsx")):
            rm_head = []
            for column in self.df.columns:
                if "Result" in column:
                    rm_head.append(column)
            data_list = self.df.drop(columns=rm_head).head(7)
        else:
            data_list = self.df.head(7)

        # 找到 "Force" 列的索引
        start_index = data_list.columns.get_loc("Force")
        # 从 "Force" 列开始获取以后的所有数据
        df_from_force = data_list.iloc[:, start_index:].values.tolist()

        return df_from_force

    def separate_information(self) -> list:
        """分离csv中间信息"""
        if self.rmNa is None:
            self.df = self.df.fillna("")  # 更新 df 减少df的错误使用
            self.rmNa = self.df.values.tolist()
            return self.rmNa
        else:
            return self.rmNa

    def testStatisticsData(self, testName: str, signal: str) -> list:
        """
        :return:  ['TestName', 'Signal', 'NO', 'Site', 'LowLimit', 'HighLimit', 'Force'])
        """
        data = self.df[(self.df['TestName'] == testName) & (self.df['Signal'] == signal)]
        measure_list = ['NO', 'Site', 'LowLimit', 'HighLimit', 'Force']
        res = [testName, signal]
        for i in measure_list:
            xyData = data[i].values[0]
            if pd.isna(xyData):  # 检查是否为NaN
                res.append("")
            else:
                res.append(xyData)
        return res


    def getTestName(self) -> list:
        """get testName"""
        """TestName = self.df["TestName"].dropna()  # 移除缺省值
        TestName = TestName.drop_duplicates().values.tolist()
        res = []
        for i in TestName:
            if i == ' ':
                continue
            res.append(i)
        res.append('ALL')"""

        filtered_df = self.df.dropna(subset=["TestName"])
        filtered_df = filtered_df[filtered_df["TestName"] != ""]
        res = filtered_df["TestName"].drop_duplicates().values.tolist()
        res.append('ALL')
        return res

    def get_file_size(self, p: str) -> str:
        """获得文件大小"""
        try:
            return "%.2f MB" % (os.stat(p).st_size / 2 ** 20)
        except Exception:
            return "?? MB"
        except SystemExit:
            pass


if __name__ == '__main__':
    datatest = DataAnalysis(R"D:\dataset\new\testcsv.csv")
    datatest.get_bin()
    # print()
    pass
